package com.diors.commons.network;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

import com.diors.commons.log.DiorsLogger;

/**
 * 调度器
 * @author	darren.ouyang
 * @data	2013-9-9
 */
public class DispatcherHandler extends SimpleChannelHandler implements Dispatcher
{
	
	private final static DiorsLogger log = DiorsLogger.getLogger(DispatcherHandler.class);
	
	private Map<Integer, DiorsConnection> conns = Collections.synchronizedMap(new HashMap<Integer, DiorsConnection>());
	
	private DiorsConnFactory connFactory;
	
	/**
	 * 构造函数
	 * @param connFactory
	 * @create	2013-9-11	darren.ouyang
	 */
	public DispatcherHandler (DiorsConnFactory connFactory)
	{
		this.connFactory = connFactory;
	}
	
	@Override
	public final void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception 
	{
		/* 新连接 */
		DiorsConnection conn = connFactory.createConnection(ctx, this);
		if (conn == null)
			return;
		
		/* 将连接设置到管道中间对象中 */
		ctx.setAttachment(conn);
		
		conns.put(ctx.getChannel().getId(), conn);
	}
	
	@Override
	public final void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception 
	{
		/* 连接关闭 */
		connectionClose((DiorsConnection) ctx.getAttachment());
		conns.remove(ctx.getChannel().getId());
	}
	

	@Override
	public final void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception 
	{
		/* 接收信息 */
		ChannelBuffer buff = (ChannelBuffer) e.getMessage();
		DiorsConnection conn = (DiorsConnection) ctx.getAttachment();
		
		ChannelBuffer rb = conn.readBuffer;
		if (buff.capacity() > rb.writableBytes())
		{
			connectionClose(conn);
			return;
		}
		
		rb.writeBytes(buff);
		
		while (rb.readableBytes() > 4 && rb.readableBytes() >= rb.getInt(rb.readerIndex()))
		{
			boolean parseResult = parse(conn, rb);
			if (!parseResult)
			{
				connectionClose(conn);
				return;
			}
		}
		
		if (rb.readable())
			rb.discardReadBytes();
		else
			rb.clear();
	}
	
	private boolean parse (DiorsConnection conn, ChannelBuffer buff)
	{
		int length = 0;

		try
		{
			length = buff.readInt();
			ChannelBuffer _buff = buff.slice();
			
			_buff.writerIndex(length);
			
			buff.readerIndex(buff.readerIndex() + length);
			
			DiorsBuffer dbuffer = new DiorsBuffer(_buff);
			ReceivablePacket packet = conn.createReceivableRacket(dbuffer);
			return packet.processData ();
		}
		catch (Exception e) 
		{
			log.warn("解析客户端的包出错-连接" + conn + "包长:" + length, e);
			return Boolean.FALSE;
		}
	}
	
	@Override
	public final void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception 
	{
		log.error(new StringBuilder("netty 错误！").toString(), e.getCause());
	}
	
	private void connectionClose (DiorsConnection conn)
	{
		
	}
}
